﻿<template>
    <span>
        <component is="style" />
        <input title="点击选择文件" ref="file" type="file" v-on:change="selectFile" :accept="params.accept" style="position: absolute; left: 0; top: 0; right: 0; bottom: 0; opacity: 0; cursor: pointer; user-select: none; display:none;" multiple="multiple" v-if="params.type=='image'" />
        <input title="点击选择文件" ref="file" type="file" v-on:change="selectFile" :accept="params.accept" style="position: absolute; left: 0; top: 0; right: 0; bottom: 0; opacity: 0; cursor: pointer; user-select: none; display:none;" v-else />
        <hxt-popup v-model="audioRecorder.show" title="录音" round closeable :close-on-click-overlay="false" :get-container="getContainer">
            <page-tip :type="audioRecorder.tipType" :title="audioRecorder.tipTitle" :btn="audioRecorder.tipBtn" v-on:btnClick="closeRecorder">
                <template>
                    <div>{{audioRecorder.tipMsg}}</div>
                    <div v-if="audioRecorder.status>=4">录音时长：{{audioRecorder.duration}}秒，大小约：{{audioRecorder.fileSize}}</div>
                </template>
                <template v-if="audioRecorder.status>=5" #btns>
                    <van-button type="primary" block round style="width:80vw; margin-top:10px;" v-on:click="audioRecorderOK">使用此录音</van-button>
                </template>
            </page-tip>
        </hxt-popup>
        <hxt-popup v-model="videoRecorder.show" title="录像" round closeable :close-on-click-overlay="false" :get-container="getContainer" style="max-height:90%;">
            <page-tip :type="videoRecorder.tipType" :btn="videoRecorder.tipBtn" v-on:btnClick="videoClick" :class="{'video-recorder':videoRecorder.status>=2}">
                <template>
                    <video v-if="videoRecorder.status>=3" ref="video" playsinline webkit-playsinline x5-video-player-type="h5" preload="metadata" :style="{width:videoRecorder.width+'px',height:videoRecorder.height+'px'}"></video>
                    <div>{{videoRecorder.tipMsg}}</div>
                    <div v-if="videoRecorder.status>=4">视频时长：{{videoRecorder.duration}}秒，大小约：{{videoRecorder.fileSize}}</div>
                </template>
                <template v-if="videoRecorder.status>=5" #btns>
                    <van-button type="primary" block round style="width:80vw; margin-top:10px;" v-on:click="videoOK">使用此视频</van-button>
                </template>
            </page-tip>
        </hxt-popup>
    </span>
</template>
<script>
    module = (function (hxt) {
        return {
            name: 'hxtFileSelector',
            props: {
                getContainer: {
                    type: [String, Function],
                    default: null
                }
            },
            data: function () {
                return {
                    isMobileBrowser: hxt.isMobileBrowser() && window.vant,
                    isIos: hxt.isIos(),

                    audioRecorder: { // 录音
                        tipType: '', // 提示Icon
                        tipTitle: '', // 提示标题
                        tipMsg: '', // 提示内容
                        tipBtn: '', // 提示按钮文字
                        duration: '', // 录音时长
                        fileSize: '', // 录音文件大小
                        status: 0, // 录音状态
                        show: false, // 录音界面是否显示
                        recorder: null // 录音对象
                    },
                    videoRecorder: {
                        show: false,
                        tipType: '', // 提示Icon
                        tipMsg: '', // 提示内容
                        tipBtn: '', // 提示按钮文字
                        duration: 0, // 录音时长
                        fileSize: '', // 录音文件大小
                        status: 0, // 录音状态
                        show: false, // 录音界面是否显示
                        recorder: null, // 录音对象
                        width: 0,
                        height: 0,
                        devices: [],
                        stream: null,
                        chunks: [],
                        timer: null,
                        size: 0
                    },
                    params: {
                        type: '', // 选择的文件类型 image | audio | video | file
                        accept: '',
                        maxWH: 0, // 选择图片时是否自动压缩图片，为 0 时不压缩，> 0 压缩至指定宽高，默认不压缩
                        maxSize: 100 * 1024 * 1024, // 限制文件大小（字节），默认 100M
                        maxDuration: 60, // 限制音频时长（秒），录音时有效，默认 60秒
                        success: function () { } // 成功回调
                    }
                };
            },
            computed: {
                extType: function () {
                    var _this = this;
                    return _this.params.type == 'image' ? 2 : _this.params.type == 'audio' ? 3 : _this.params.type == 'video' ? 4 : _this.params.type == 'file' ? 7 : -1;
                }
            },
            watch: {
                'audioRecorder.show': function (val) {
                    if (!val) this.destroy();
                },
                'videoRecorder.show': function (val) {
                    if (!val) {
                        var _this = this, videoRecorder = _this.videoRecorder;
                        _this.videoStop(videoRecorder.stream);

                        if (!!videoRecorder.recorder) videoRecorder.stop();

                        if (!!videoRecorder.timer) {
                            clearInterval(videoRecorder.timer);
                            videoRecorder.timer = null;
                        }

                        !!_this.$refs['video'] && _this.$refs['video'].pause();
                    }
                }
            },
            activated: function () { },
            mounted: function () {
            },
            destroyed: function () {
                this.destroy();
            },
            methods: {
                chooseFile: function (params) {
                    var _this = this, x = params || {};

                    _this.params.type = '';
                    if (!!x.type) _this.params.type = x.type;

                    if (['image', 'audio', 'video', 'file'].indexOf(_this.params.type) < 0) return hxt.error('参数无效');

                    _this.params.accept = '';

                    _this.params.maxSize = 100 * 1024 * 1024;
                    if (!!x.maxSize) {
                        var maxSize = Number(x.maxSize);
                        if (!isNaN(maxSize) && maxSize >= 0) _this.params.maxSize = maxSize;
                    }

                    _this.params.maxDuration = 60;
                    if (!!x.maxDuration) {
                        var maxDuration = Number(x.maxDuration);
                        if (!isNaN(maxDuration) && maxDuration >= 0) _this.params.maxDuration = maxDuration;
                    }

                    _this.params.maxWH = 0;
                    if (!!x.maxWH) {
                        var maxWH = Number(x.maxWH);
                        if (!isNaN(maxWH) && maxWH >= 0) _this.params.maxWH = maxWH;
                    }

                    _this.params.success = function () { };
                    if (hxt.isFunction(x.success)) _this.params.success = x.success;

                    //手机端录音
                    if (_this.params.type == 'audio') {
                        if (_this.isMobileBrowser) {
                            _this.showRecorder();
                            return;
                        }
                    }
                    //else if (_this.params.type == 'video') {
                    //    if (_this.isMobileBrowser) {
                    //        _this.videoShow();
                    //        return;
                    //    }
                    //}

                    //触发选择文件
                    _this.params.accept = hxt.getFileMimeStr(_this.extType);
                    _this.$nextTick(function () {
                        _this.$refs['file'].click();
                    });
                },
                selectFile: function (e) {
                    var _this = this, files = e.target.files;
                    if (files.length == 0) return;
                    //var file = files[0];
                    //!!_this.$refs['file'] && (_this.$refs['file'].value = '');
                    $.each(files, function (idx, file) {
                        if (idx > 8) return;
                        //校验大小
                        if (file.size == 0) return hxt.error('请勿选择空文件');
                        if (_this.params.maxSize > 0 && file.size > _this.params.maxSize) return hxt.error('文件最大不可超过' + hxt.getFileSize(_this.params.maxSize));
                        //校验扩展名
                        var ext = file.name.toLowerCase().split('.').splice(-1).join('');
                        if (hxt.getFileExtList(_this.extType).indexOf(ext) < 0) return hxt.error('仅支持' + hxt.getFileExtStr(_this.extType) + '扩展名的文件');
                        // 如果是图片，压缩
                        // 如果是音频或视频，获取文件时长
                        var res = {
                            file: file,
                            fullName: file.name,
                            name: file.name.substr(0, file.name.length - ('.' + ext).length),
                            ext: '.' + ext,
                            size: file.size,
                            sizeStr: hxt.getFileSize(file.size),
                            duration: null,
                            base64: null
                        };

                        if (_this.params.type == 'image') {
                            if (_this.params.maxWH > 0) {

                                var base64ToBlob = function (base64, type) {
                                    var arr = base64.split(',');
                                    var mime = arr[0].match(/:(.*?);/)[1] || type;
                                    var bytes = window.atob(arr[1]);
                                    var ab = new ArrayBuffer(bytes.length);
                                    var ia = new Uint8Array(ab);
                                    for (var i = 0; i < bytes.length; i++) {
                                        ia[i] = bytes.charCodeAt(i);
                                    }
                                    return new Blob([ia], { type: mime });
                                };

                                hxt.compressImg(file, _this.params.maxWH, function (id, raw64, base64) {
                                    var blob = base64ToBlob(base64);
                                    res.file = new File([blob], res.fullName, { type: blob.type });
                                    res.size = res.file.size;
                                    res.sizeStr = hxt.getFileSize(res.file.size);
                                    res.base64 = base64;
                                    _this.callBack(res);
                                });
                            }
                            else {
                                var reader = new FileReader();
                                reader.onload = function (e) {
                                    res.base64 = e.target.result;
                                    _this.callBack(res);
                                };
                                reader.readAsDataURL(file);
                            }
                            return;
                        }
                        else if (_this.params.type == 'audio') {
                            hxt.mask();
                            var audio = new Audio(URL.createObjectURL(file));
                            // ios无法触发loadedmetadata，所以要静音播放
                            audio.muted = true;
                            audio.onloadedmetadata = function (e) {
                                hxt.unmask();
                                res.duration = audio.duration;
                                _this.callBack(res);
                            };
                            audio.onerror = function (e) {
                                hxt.unmask();
                                return hxt.error('音频文件无效');
                            };
                            audio.play().then(function (e) {
                                audio.pause();
                            });
                        }
                        else if (_this.params.type == 'video') {
                            hxt.mask();
                            var audio = new Audio(URL.createObjectURL(file));
                            // ios无法触发loadedmetadata，所以要静音播放
                            audio.muted = true;
                            audio.onloadedmetadata = function (e) {
                                hxt.unmask();
                                res.duration = audio.duration;
                                _this.callBack(res);
                            };
                            audio.onerror = function (e) {
                                hxt.unmask();
                                return hxt.error('视频文件无效');
                            };
                            audio.play().then(function (e) {
                                audio.pause();
                            });
                        }
                        else {
                            _this.callBack(res);
                        }
                    });
                    !!_this.$refs['file'] && (_this.$refs['file'].value = '');
                },
                callBack: function (res) {
                    var _this = this;
                    hxt.isFunction(_this.params.success) && _this.params.success(res);
                },
                //#region
                isApiOK: function () {
                    return 'mediaDevices' in navigator && 'getUserMedia' in navigator.mediaDevices && 'MediaRecorder' in window;
                },
                videoShow: function () {
                    var _this = this, videoRecorder = _this.videoRecorder;
                    _this.videoStatus(0, 'loading', '加载中，请稍后...', '');
                    videoRecorder.show = true;
                    _this.videoLoad();
                },
                videoStatus: function (status, tipType, tipMsg, tipBtn) {
                    var _this = this, videoRecorder = _this.videoRecorder;
                    videoRecorder.status = status;
                    $.extend(videoRecorder, { tipType: tipType, tipMsg: tipMsg, tipBtn: tipBtn });
                },
                videoStop: function (stream) {
                    if (!stream) return;
                    stream.getVideoTracks().map(function (x) { x.stop(); });
                    stream.getAudioTracks().map(function (x) { x.stop(); });
                },
                videoLoad: function () {
                    var _this = this, videoRecorder = _this.videoRecorder;
                    if (!_this.isApiOK()) {
                        _this.videoStatus(1, 'info', 'Media Capture ApI is not supported', '关闭');
                        return;
                    }

                    videoRecorder.devices = [];
                    navigator.mediaDevices.getUserMedia({ video: true, audio: true })
                        .then(function (res) {
                            _this.videoStop(res);
                            navigator.mediaDevices.enumerateDevices()
                                .then(function (res) {
                                    //hxt.alert(JSON.stringify(res));
                                    res.forEach(function (item) {
                                        if (item.kind === 'videoinput') {
                                            videoRecorder.devices.push(item);
                                        }
                                    });
                                    var item = videoRecorder.devices.find(function (x) { return x.label.indexOf('2 2') > 0; });
                                    if (!item) item = videoRecorder.devices.find(function (x) { return x.label.indexOf('0') > 0; });
                                    if (!item) item = videoRecorder.devices.length > 0 ? videoRecorder.devices[videoRecorder.devices.length - 1] : null;
                                    _this.videoChange(item);

                                    //_this.videoStatus(2, 'none', '请选择摄像头', '');
                                })
                                .catch(function (res) {
                                    _this.videoStatus(1, 'info', res, '关闭');
                                });
                        })
                        .catch(function (res) {
                            _this.videoStatus(1, 'info', res, '关闭');
                        });
                },
                videoChange: function (item) {
                    var _this = this, videoRecorder = _this.videoRecorder;

                    videoRecorder.width = document.documentElement.clientWidth - 60 * 2;
                    if (videoRecorder.width > 300) videoRecorder.width = 300;
                    videoRecorder.height = videoRecorder.width / 3 * 4;

                    var constraints = {
                        video: {
                            facingMode: { exact: "environment" },
                            focusMode: { ideal: "continuous" },
                            width: { ideal: 720 },
                            height: { ideal: 480 },
                            frameRate: { ideal: 30, max: 60 },
                            //deviceId: { exact: item.deviceId }
                        },
                        audio: {
                            channelCount: 1,
                            sampleRate: 16000,
                            sampleSize: 16,
                            volume: 1
                        }
                    };

                    if (!!item && !!item.deviceId) {
                        constraints.video.deviceId = { exact: item.deviceId };
                    }

                    //hxt.alert(JSON.stringify(constraints));

                    videoRecorder.chunks = [];
                    navigator.mediaDevices.getUserMedia(constraints)
                        .then(function (res) {
                            videoRecorder.stream = res;

                            getSupportedMimeTypes = function () {
                                var arr = [];
                                var types = ['webm', 'mp4', 'ogg', 'mov', 'avi', 'wmv', 'flv', 'mkv', 'ts', 'x-matroska'];
                                var codecs = ['', 'vp9', 'vp9.0', 'vp8', 'vp8.0', 'avc1', 'av1', 'h265', 'h264'];
                                types.map(function (type) {
                                    codecs.map(function (code) {
                                        var mime = 'video/' + type + (!!code ? ';codecs=' + code : '');
                                        if (MediaRecorder.isTypeSupported(mime)) arr.push(mime);
                                    });
                                });
                                return arr;
                            };

                            //hxt.alert(JSON.stringify(getSupportedMimeTypes()));

                            var options = { audioBitsPerSecond: 128000, videoBitsPerSecond: 3000000 };

                            if (MediaRecorder.isTypeSupported('video/mp4')) options['mimeType'] = 'video/mp4';
                            else if (MediaRecorder.isTypeSupported('video/webm;codecs=avc1')) options['mimeType'] = 'video/webm;codecs=avc1';
                            else if (MediaRecorder.isTypeSupported('video/webm;codecs=h264')) options['mimeType'] = 'video/webm;codecs=avc1';
                            else if (MediaRecorder.isTypeSupported('video/webm')) options['mimeType'] = 'video/webm';

                            //hxt.alert(JSON.stringify(options));

                            var recorder = new MediaRecorder(res, options);

                            recorder.onerror = function (e) {
                                _this.videoStatus(1, 'info', '视频录制失败：' + e, '关闭');
                            };

                            recorder.ondataavailable = function (e) {
                                videoRecorder.chunks.push(e.data);

                                videoRecorder.size += e.data.size;
                                videoRecorder.fileSize = hxt.getFileSize(videoRecorder.size);

                                //var blob = new Blob(videoRecorder.chunks, { type: "video/mp4" });
                                //videoRecorder.fileSize = hxt.getFileSize(blob.size);
                                //blob = null;
                            };

                            recorder.onstart = function () {
                                videoRecorder.timer = setInterval(function () {
                                    var x = Number(videoRecorder.duration) + 0.05;
                                    videoRecorder.duration = x.toFixed(2);

                                    var max = _this.params.maxDuration <= 0 ? 0 : _this.params.maxDuration;
                                    if (max > 0 && videoRecorder.duration >= max) {
                                        recorder.stop();
                                    }
                                }, 50);

                                _this.videoStatus(4, '', '正在录像', '停止录像');
                            };

                            recorder.onstop = function () {
                                _this.videoStop(videoRecorder.stream);

                                if (!!videoRecorder.timer) {
                                    clearInterval(videoRecorder.timer);
                                    videoRecorder.timer = null;
                                }

                                var video = _this.$refs['video'];
                                video.srcObject = null;


                                video.onloadeddata = function (e) {
                                    video.pause();
                                    video.muted = false;
                                };

                                video.onplay = function (e) {
                                    _this.videoStatus(5, '', '正在播放', '暂停');
                                };

                                video.onpause = function (e) {
                                    _this.videoStatus(5, '', '播放暂停', '播放');
                                };

                                video.onended = function (e) {
                                    _this.videoStatus(5, '', '播放结束', '播放');
                                };

                                _this.videoStatus(5, 'none', '录制结束', '播放');

                                var blob = new Blob(videoRecorder.chunks, { type: 'video/mp4' });
                                var url = URL.createObjectURL(blob);
                                video.src = url;
                                video.play();
                            };

                            videoRecorder.recorder = recorder;
                            videoRecorder.duration = 0;
                            videoRecorder.fileSize = '';
                            videoRecorder.size = 0;
                            _this.videoStatus(3, 'none', '请点击下方按钮开始录像', '开始录像');

                            _this.$nextTick(function () {
                                var video = _this.$refs['video'];
                                video.muted = true;
                                video.srcObject = res;
                                video.play();
                            });
                        })
                        .catch(function (res) {
                            _this.videoStatus(1, 'info', res, '关闭');
                        });
                },
                videoClick: function () {
                    var _this = this, videoRecorder = _this.videoRecorder, btn = videoRecorder.tipBtn, recorder = videoRecorder.recorder;

                    if (btn == '关闭') return videoRecorder.show = false;

                    if (btn == '开始录像') {
                        recorder.start(50);
                        return;
                    }

                    if (btn == '停止录像') {
                        recorder.stop();
                        return;
                    }

                    if (btn == '播放' || btn == '继续播放') {
                        _this.$refs['video'].play();
                        return;
                    }

                    if (btn == '暂停') {
                        _this.$refs['video'].pause();
                        return;
                    }
                },
                videoOK: function () {
                    var _this = this, videoRecorder = _this.videoRecorder;
                    var blob = new Blob(videoRecorder.chunks, { type: 'video/mp4' });
                    var res = {
                        file: null,
                        fullName: '录像-' + hxt.dateFormat('yyyyMMddHHmmss') + '.mp4',
                        name: '',
                        ext: '.mp4',
                        size: 0,
                        sizeStr: '',
                        duration: videoRecorder.duration,
                        cvtmp4: 1
                    };
                    res.file = new File([blob], res.fullName, { type: blob.type });
                    res.size = res.file.size;
                    res.sizeStr = hxt.getFileSize(res.file.size)
                    res.name = res.fullName.substr(0, res.fullName.length - res.ext.length);
                    !!_this.$refs['video'] && _this.$refs['video'].pause();
                    videoRecorder.show = false;
                    _this.callBack(res);
                },
                //#endregion
                //#region 录音 https://recorder.api.zhuyuntao.cn/Recorder/start.html
                update: function (status, tipType, tipTitle, tipMsg, tipBtn) {
                    var _this = this, audioRecorder = _this.audioRecorder;
                    audioRecorder.status = status;
                    $.extend(audioRecorder, { tipType: tipType, tipTitle: tipTitle, tipMsg: tipMsg, tipBtn: tipBtn });
                },
                destroy: function (callback) {
                    var _this = this, audioRecorder = _this.audioRecorder, recorder = audioRecorder.recorder;
                    if (!recorder) {
                        hxt.isFunction(callback) && callback();
                        return;
                    }
                    audioRecorder.recorder = null;
                    if (audioRecorder.status == 6) recorder.stopPlay();
                    if (audioRecorder.status == 4) recorder.stop();
                    recorder.destroy().then(function () {
                        recorder = null;
                        hxt.isFunction(callback) && callback();
                    });
                },
                load: function () {
                    var _this = this;
                    hxt.loadJs({
                        maskText: '加载插件[1/2]，请稍后...',
                        url: 'https://hxt2017.oss-cn-hangzhou.aliyuncs.com/static/index/js-audio-recorder/recorder.js',
                        ok: function () {
                            hxt.loadJs({
                                maskText: '加载插件[2/2]，请稍后...',
                                url: 'https://hxt2017.oss-cn-hangzhou.aliyuncs.com/static/index/js-audio-recorder/lame.min.js',
                                ok: function () {
                                    _this.initRecorder();
                                },
                                showErr: false,
                                error: function (err) {
                                    _this.update(1, 'info', '加载失败', '[lame]' + err, '关闭');
                                }
                            });
                        },
                        showErr: false,
                        error: function (err) {
                            _this.update(1, 'info', '加载失败', '[recorder]' + err, '关闭');
                        }
                    });
                },
                initRecorder: function () {
                    var _this = this, audioRecorder = _this.audioRecorder;
                    Recorder.getPermission().then(function () {
                        audioRecorder.duration = 0;
                        audioRecorder.fileSize = '';
                        _this.update(2, 'clock', '', '请点击下方按钮开始录音', '开始录音');

                        audioRecorder.recorder = new Recorder({
                            sampleBits: 16,                 // 采样位数，支持 8 或 16，默认是16
                            sampleRate: 16000,              // 采样率，支持 11025、16000、22050、24000、44100、48000，根据浏览器默认值，我的chrome是48000
                            numChannels: 1,                 // 声道，支持 1 或 2， 默认是1
                        });

                        audioRecorder.recorder.onprogress = function (params) {
                            audioRecorder.duration = params.duration.toFixed(2);
                            audioRecorder.fileSize = hxt.getFileSize(params.fileSize);

                            var max = _this.params.maxDuration <= 0 ? 0 : _this.params.maxDuration;
                            if (max > 0 && audioRecorder.duration >= max) {
                                audioRecorder.recorder.stop();
                                _this.update(5, 'success', '录音已停止', '', '试听');
                            }
                        };

                        audioRecorder.recorder.onplayend = function () {
                            _this.update(5, 'success', '试听结束', '', '试听');
                        }

                    }, function (error) {
                        _this.update(3, 'danger', '录音未授权', error.name + '：' + error.message, '关闭');
                    });
                },
                showRecorder: function () {
                    var _this = this, audioRecorder = _this.audioRecorder;
                    _this.update(0, 'loading', '', '加载中，请稍后...', '');
                    audioRecorder.show = true;
                    _this.load();
                },
                closeRecorder: function () {
                    var _this = this, audioRecorder = _this.audioRecorder, btn = audioRecorder.tipBtn, recorder = audioRecorder.recorder;

                    if (btn == '关闭') return audioRecorder.show = false;

                    if (btn == '开始录音') {
                        recorder.start().then(function () {
                            // 开始录音
                            _this.update(4, 'clock', '正在录音', '', '停止录音');
                        }, function (error) {
                            _this.update(3, 'danger', '出错了，' + error.name + '：' + error.message, '关闭');
                        });
                        return;
                    }

                    if (btn == '停止录音') {
                        recorder.stop();
                        _this.update(5, 'success', '录音已停止', '', '试听');
                        return;
                    }

                    if (btn == '试听') {
                        recorder.play();
                        _this.update(6, 'success', '正在试听', '', '暂停');
                        return;
                    }

                    if (btn == '暂停') {
                        recorder.pausePlay();
                        _this.update(5, 'success', '试听暂停', '', '继续试听');
                        return;
                    }

                    if (btn == '继续试听') {
                        recorder.resumePlay();
                        _this.update(6, 'success', '正在试听', '', '暂停');
                        return;
                    }
                },
                convertToMp3: function (wavDataView) {
                    var _this = this, audioRecorder = _this.audioRecorder, recorder = audioRecorder.recorder;
                    // 获取wav头信息
                    var wav = lamejs.WavHeader.readHeader(wavDataView); // 此处其实可以不用去读wav头信息，毕竟有对应的config配置
                    var channels = wav.channels, sampleRate = wav.sampleRate;
                    var mp3enc = new lamejs.Mp3Encoder(channels, sampleRate, 128);
                    // 获取左右通道数据
                    var result = recorder.getChannelData()
                    var buffer = [];

                    var leftData = result.left && new Int16Array(result.left.buffer, 0, result.left.byteLength / 2);
                    var rightData = result.right && new Int16Array(result.right.buffer, 0, result.right.byteLength / 2);
                    var remaining = leftData.length + (rightData ? rightData.length : 0);

                    var maxSamples = 1152;
                    for (var i = 0; i < remaining; i += maxSamples) {
                        var left = leftData.subarray(i, i + maxSamples);
                        var right = null;
                        var mp3buf = null;

                        if (channels === 2) {
                            right = rightData.subarray(i, i + maxSamples);
                            mp3buf = mp3enc.encodeBuffer(left, right);
                        } else {
                            mp3buf = mp3enc.encodeBuffer(left);
                        }

                        if (mp3buf.length > 0) {
                            buffer.push(mp3buf);
                        }
                    }

                    var enc = mp3enc.flush();

                    if (enc.length > 0) {
                        buffer.push(enc);
                    }
                    return new Blob(buffer, { type: 'audio/mp3' });
                },
                audioRecorderOK: function () {
                    var _this = this, audioRecorder = _this.audioRecorder, recorder = audioRecorder.recorder;
                    var mp3 = _this.convertToMp3(recorder.getWAV());
                    var res = {
                        file: null,
                        fullName: '录音-' + hxt.dateFormat('yyyyMMddHHmmss') + '.mp3',
                        name: '',
                        ext: '.mp3',
                        size: 0,
                        sizeStr: '',
                        duration: audioRecorder.duration
                    };
                    res.file = new File([mp3], res.fullName, { type: mp3.type });
                    res.size = res.file.size;
                    res.sizeStr = hxt.getFileSize(res.file.size)
                    res.name = res.fullName.substr(0, res.fullName.length - res.ext.length);
                    audioRecorder.show = false;
                    _this.callBack(res);
                }
                //#endregion
            },
            components: {
                pageTip: (function () {
                    return !!hxt.pageTip ? hxt.pageTip() : {};
                })(),
                hxtPopup: (function () {
                    return !!hxt.hxtPopup ? hxt.hxtPopup() : {}
                })()
            }
        };
    })(window.$jscript.fn);
</script>
<style>
    .video-recorder {
        background-color: #2E2E2E;
        padding-top: 0;
    }

        .video-recorder video {
            background-color: #242424;
        }

        .video-recorder .van-empty__image {
            display: none;
        }
</style>